package com.atguigu.gmall.order.controller;

import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Description:
 * @author: JC
 * @date: 2021/11/9 12:43
 */
@RestController
@RequestMapping("api/order")
public class OrderApiController {
    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private OrderService orderService;


    /**
     * 内部调用获取订单
     * @param orderId
     * @return
     */
    @GetMapping("inner/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable(value = "orderId") Long orderId){
        return orderService.getOrderInfo(orderId);
    }

    /**
     * 去订单页面订单
     * @param request
     * @return
     */
    @GetMapping("auth/trade")
    public Result<Map<String, Object>> trade(HttpServletRequest request){
        HashMap<String, Object> map = new HashMap<>();
        String userId = AuthContextHolder.getUserId(request);
        // 远程调用获取收获地址
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.parseLong(userId));
        map.put("userAddressList",userAddressList);

        // 获取送货清单
        List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(userId);
        // cartCheckedList的集合数据赋值给订单明细集合
        ArrayList<OrderDetail> orderDetails = new ArrayList<>();

        int[] totalNum = new int[1];
        cartCheckedList.stream().forEach(cartInfo -> {
            totalNum[0] += cartInfo.getSkuNum();
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cartInfo,orderDetail);
            orderDetail.setOrderPrice(cartInfo.getSkuPrice());
            orderDetail.setCreateTime(new Date());
            orderDetails.add(orderDetail);
        });

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderDetailList(orderDetails);
        orderInfo.sumTotalAmount();
        map.put("totalAmount", orderInfo.getTotalAmount());
        // 件数： 第一种： 就看集合的长度， 第二种： 计算每个skuId的总件数
        map.put("totalNum",totalNum[0]);
        map.put("detailArrayList",orderDetails);

        // 获取流水号，并存储 防止无刷新重复提交
        String tradeNo = orderService.getTradeNo(userId);
        map.put("tradeNo",tradeNo);

        return Result.ok(map);
    }



    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        // 获取页面传递的交易号
        String tradeNo = request.getParameter("tradeNo");
        // 调用比较方法
        Boolean result = orderService.checkedTradeNo(tradeNo, userId);
        if(!result){
            // 比较失败
            return Result.fail("不能重复提交订单！");
        }
        orderService.deleteTradeNo(userId);
        orderInfo.setUserId(Long.parseLong(userId));

        // 验证库存：
        /*List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            // 验证库存：
//            boolean result = orderService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
//            if (!result) {
//                return Result.fail().message(orderDetail.getSkuName() + "库存不足！");
//            }
            // 验证价格：

            BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
            if (orderDetail.getOrderPrice().compareTo(skuPrice) != 0) {
                // 重新查询价格！
                cartFeignClient.loadCartCache(userId);
                return Result.fail().message(orderDetail.getSkuName() + "价格有变动！");
            }
        }*/

        List<String> errorList = new ArrayList<>();
        List<CompletableFuture> futureList = new ArrayList<>();
        // 验证库存：
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            /*CompletableFuture<Void> checkStockCompletableFuture = CompletableFuture.runAsync(() -> {
                // 验证库存：
                boolean result = orderService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
                if (!result) {
                    errorList.add(orderDetail.getSkuName() + "库存不足！");
                }
            }, threadPoolExecutor);
            futureList.add(checkStockCompletableFuture);*/

            CompletableFuture<Void> checkPriceCompletableFuture = CompletableFuture.runAsync(() -> {
                // 验证价格：
                BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
                if (orderDetail.getOrderPrice().compareTo(skuPrice) != 0) {
                    // 重新查询价格！
                    cartFeignClient.loadCartCache(userId);
                    errorList.add(orderDetail.getSkuName() + "价格有变动！");
                }
            });
            futureList.add(checkPriceCompletableFuture);
        }

        //合并线程
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
        if(errorList.size() > 0) {
            return Result.fail().message(StringUtils.join(errorList, ","));
        }


        Long orderId = orderService.saveOrderInfo(orderInfo);

        return Result.ok(orderId);
    }


}
